<?php

namespace WeiPu\Shop\Http\Controllers;

use Illuminate\Routing\Controller;
use ZipArchive;
use Illuminate\Support\Facades\DB;
use WeiPu\Shop\Models\PluginModel;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema;

class InstallController extends Controller
{

    /**
     * 下载zip
     */
    public function downZip($zip, $name, $is_app)
    {
        if ($is_app === 1) {
            return $this->bigFileDown($zip, $name);
        } 
        return $this->downloadRemoteFile($zip, $name);
    }

    private function bigFileDown($url, $name)
    {
        $savePath = storage_path($name . '.zip');
        // 初始化 cURL  
        $ch = curl_init($url);  
        // 设置 cURL 选项  
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, false); // 不返回数据，直接输出  
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向  
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 如果你不验证 SSL 证书，设置为 false（非生产环境使用）  
        curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) use ($savePath) {  
            // 写入数据到文件  
            $fp = fopen($savePath, 'ab'); // 'ab' 模式表示追加二进制数据  
            if ($fp) {  
                fwrite($fp, $data);  
                fclose($fp);  
                return strlen($data); // 返回写入的字节数  
            }  
            return false;  
        });  
        
        // 开始 cURL 传输  
        $success = curl_exec($ch);  
        
        // 检查是否成功  
        if ($success === false) {  
            $error = curl_error($ch);  
            return 'cURL Error: ' . $error;  
        }
        
        // 关闭 cURL 句柄  
        curl_close($ch);  

        return $savePath;
    }

    /**
     * 下载文件到本地文件系统中的方法
     */
    private function downloadRemoteFile($zip, $name)
    {

        $file = $this->url_get_contents($zip);
        // dd($zip,$file );
        $path = storage_path($name . '.zip');

        if ($file) {
            $pfile = file_put_contents($path, $file);
            if ($pfile) {
                return $path;
            }
        }

        return false;
    }

    protected function url_get_contents($url)
    {
        if (function_exists('curl_exec')) {
            $conn = curl_init($url);
            curl_setopt($conn, CURLOPT_SSL_VERIFYPEER, true);
            curl_setopt($conn, CURLOPT_FRESH_CONNECT,  true);
            curl_setopt($conn, CURLOPT_RETURNTRANSFER, 1);
            $url_get_contents_data = (curl_exec($conn));
            curl_close($conn);
        } elseif (function_exists('file_get_contents')) {
            $url_get_contents_data = file_get_contents($url);
        } elseif (function_exists('fopen') && function_exists('stream_get_contents')) {
            $handle = fopen($url, "r");
            $url_get_contents_data = stream_get_contents($handle);
        } else {
            $url_get_contents_data = false;
        }
        return $url_get_contents_data;
    }

    /**
     * 解压缩文件到指定目录中 或从指定文件中解压缩文件到另一个目录中
     */
    public function unZip($zip_pass, $path, $name)
    {
        // 判断 ZipArchive 是否可用  
        if (!class_exists('ZipArchive')) {
            return 'ZipArchive 扩展没有安装';
        }
        // 创建一个新的 ZipArchive 实例  
        $zip = new ZipArchive();
        // 打开有密码的压缩包  
        $zip->open($path);
        if ($zip_pass) {
            // 设置密码  
            $zip->setPassword($zip_pass);
        }
        // 解锁压缩包  
        $res = $zip->extractTo(storage_path());
        $zip->close();

        return $res;
    }

    /**
     * 安装文件
     */
    public function installZip($name, $title)
    {
        $file = storage_path($name . '/install.php');

        $install = false;

        if (file_exists($file)) {
            // $conf = File::get($file, $lock = false);
            $conf = include($file);
            // dd($conf);
            foreach ($conf as $key => $value) {
                // 处理菜单
                if ($key == 'menu') {
                    // 把路由写入文件
                    $routeUrl = base_path() . '/addons/weipu/shop/src/Http/routes.php';
                    $routes = file_get_contents($routeUrl);
                    if ($routes) {
                        file_put_contents($routeUrl, $value, FILE_APPEND);
                    }
                    $menuData = [
                        'title' => $title,
                        'uri' => $name
                    ];
                    $adminMenuId =  DB::table('admin_menu')->where($menuData)->value('id');
                    if (!$adminMenuId) {
                        // 写入数据库
                        DB::table('admin_menu')->insert($menuData);
                    }

                    continue;
                }
                if ($key == 'table') {
                    // 安装的时候不考虑数据库
                    continue;
                }
                if ($key == 'route') {
                    // dd(base_path());
                    if (is_array($value)) {
                        foreach ($value as $ke => $val) {
                            // 把路由写入文件
                            $routeUrl = base_path() . '/routes/api.php';
                            $routes = file_get_contents($routeUrl);
                            // dd($routes);
                            if ($routes) {
                                file_put_contents($routeUrl, $val . "\n", FILE_APPEND);
                            }
                        }
                    }
                    continue;
                }
                // 检查目录是否存在
                $this->checkCreateDir($value);
                copy(storage_path($name . $key), $value);
            }
            $install = $conf;
        }

        return $install;
    }

    /**
     * 检查目录并创建目录
     */
    private function checkCreateDir($path)
    {
        // 拆分路径为数组  
        $directories = explode('/', $path);  
        // 去掉文件名  
        array_pop($directories);  
        // 初始化变量用于存储检查过的目录  
        $checkedDirectories = [];  
        // 遍历目录  
        foreach ($directories as $directory) {  
            // 拼接目录路径  
            $currentPath = './' . implode('/', $checkedDirectories) . '/' . $directory;  
        
            // 检查目录是否存在  
            if (!is_dir($currentPath)) {  
                // echo "目录不存在: $currentPath";  
                // 创建目录
                mkdir($currentPath, 0777, true);
            } else {  
                // 目录存在，添加到已检查的目录列表中  
                $checkedDirectories[] = $directory;  
            }  
        }
    }

    /**
     * 安装sql
     */
    public function installSql($name ,$updateSql)
    {
        $sqlName = $updateSql ? 'update' : $name;
        // 导入sql文件
        $file = storage_path($name . '/' . $sqlName . '.sql');
        // dd(file_exists($file));
        if (!file_exists($file)) {
            return false;
        }
        $sql = file_get_contents($file);
        // dd($file, $sql);
        if (!$sql) {
            return false;
        }
        return DB::unprepared($sql);
    }

    /**
     * 删除下载文件
     */
    public function delZip($name)
    {
        // 删除文件
        $tableDir = storage_path($name);
        File::cleanDirectory($tableDir);
        // 删除目录
        File::deleteDirectory($tableDir, $preserve = false);
        // 删除zip
        File::delete($tableDir . '.zip');
    }

    /**
     * 写入安装日志
     * @param name 名称
     * @param item 数据
     */
    public function installLog($item, $name)
    {
        // dd($item);
        $plug = PluginModel::where('name', $item['name'])->first();
        if ($plug) {
            $plugId = $plug->id;
            if ($plug->conf) {
                $arrConf= json_decode($plug->conf, true);
                // dd( $plug->conf);
                $arrConf[$name] = $item['conf'];
                // dd( $arrConf);
                $item['conf'] = json_encode($arrConf);
            }
        } else {
            $plugId = 0;
            $item['conf'] = json_encode([$name=>$item['conf']]);
        }
        
        $data = [
            'name' => $item['name'],
            'title' => $item['title'],
            'description' => $item['describe'],
            'version' => $item['version'],
            'author' => $item['user_id'],
            'conf' => $item['conf'],
        ];
        if ($plugId) {
            // 更新
            $data['updated_at'] = date('Y-m-d H:i:s');
            PluginModel::where('id', $plugId)->update($data);
        } else {
            $data['created_at'] = date('Y-m-d H:i:s');
            PluginModel::insert($data);
        }

        return true;
    }

    /**
     * 卸载插件
     * @param name 名称
     * @param title 标题
     */
    public function uninstall($name, $paceappsName, $titles)
    {
        // 通过安装的配置文件查询出所安装的文件
        $conf = PluginModel::where('name', $name)->value('conf');
        $confArrs = json_decode($conf, true);
         // 通过描述判断是否多应用
         if (strstr($paceappsName, ',')) {
            $arrName = explode(',', $paceappsName);
            $arrTitle= explode(',', $titles);
        } else {
            $arrName = [$name];
            $arrTitle = [$titles];
        }
        if (is_array($arrName)) {
            foreach ($arrName as $key => $value) {
                $title = $arrTitle[$key];
                $confArr = json_decode($confArrs[$value], true);
                $this->unInstallFile($confArr, $value, $title);
            }
        }
        // 删除安装记录
        $a = PluginModel::where('name', $name)->delete();
        // dd($a);
        return true;
    }

    /**
     * 处理删除文件
     * @param conf 配置文件
     * @param name 名称
     * @param title 标题
     */
    protected function unInstallFile($conf, $name, $title)
    {
        // dump($conf);
        if (!is_array($conf)) {
            if ($name == 'vendor') {
                return false;
            }
            // 卸载sql
            $targetFolder = base_path('addons' . DIRECTORY_SEPARATOR .$name);
            $sql = File::get($targetFolder . DIRECTORY_SEPARATOR . 'uninstall.sql');
            if ($sql) {
                DB::unprepared($sql);
            }
            // dd($targetFolder);
            File::cleanDirectory($targetFolder);
            // 删除目录
            File::deleteDirectory($targetFolder, $preserve = false);
            // dd($targetFolder);
            return false;
        }
        foreach ($conf as $key => $value) {
            // 处理菜单
            if ($key == 'menu') {
                // 把路由在文件中删除
                $routeUrl = base_path() . '/addons/weipu/shop/src/Http/routes.php';
                $routes = file_get_contents($routeUrl);
                if ($routes) {
                    $routesUp = str_replace($value, '', $routes);

                    file_put_contents($routeUrl, $routesUp);
                }
                $menuData = [
                    'title' => $title,
                    'uri' => $name
                ];
                // 删除菜单
                DB::table('admin_menu')->where($menuData)->delete();
                continue;
            }
            if ($key == 'table') {
                $table = Schema::hasTable($value);
                if ($table) {
                    // 卸载数据库
                    DB::statement('drop table ' . $value);
                }
                continue;
            }
            if ($key == 'route') {
                if (is_array($value)) {
                    $routeUrl = base_path() . '/routes/api.php';
                    foreach ($value as $ke => $val) {
                        // 把路由在文件中删除
                        $routes = file_get_contents($routeUrl);
                        if ($routes) {
                            $routesUp = str_replace($val . "\n", '', $routes);
                            file_put_contents($routeUrl, $routesUp);
                        }
                    }
                }
                continue;
            }
            File::delete($value);
        }
    }
}
